
import GridConf from "@/core/GridConf";
import StructElementMgr from "../StructElement/StructElementMgr";
import { IStructInitInfo } from "../StructElement/type";
import { registryDropEvent } from "./events"
import { getGridWidth, getGridHeight } from "@/core/locationService"
import { getLeft, getTop, getHeight, getWidth } from "@/core/locationService"
export let currentGridInfo = {
    gridWidth: 0,
    gridHeight: 0,
    waterTank: 0
};
let currentShowArea = {
    top: 0,
    left: 0,
    width: 0,
    height: 0,
}
const SplitLineWidth = 1;
const SplitLineColor = "#A3C3FF";
const SplitSubLineColor = "#ddd";
const ShadowBackgroundColor = "#e5ecff";
export default class PlayGroundCanvas {
    private container: HTMLElement;
    private canvasElement: HTMLCanvasElement;
    private canvasContext: CanvasRenderingContext2D | null;
    private playgroundWidth: number = 0;
    private playgroundHeight: number = 0;
    private lineColor: string = SplitLineColor;
    private girdLayer: HTMLCanvasElement;
    private shadowLayer: HTMLCanvasElement;
    private shadowContext: CanvasRenderingContext2D | null;
    private waterTank: number = 0;
    constructor(container: HTMLElement, waterTank: number = 12, playGroundWidth: number = 1920, playGroundHeight: number = 1080) {
        this.container = container;
        this.waterTank = waterTank;
        this.canvasElement = document.createElement("canvas");
        this.girdLayer = document.createElement("canvas");
        this.shadowLayer = document.createElement("canvas");
        this.setPlaygroundSize(playGroundWidth, playGroundHeight);
        this.canvasContext = this.canvasElement.getContext("2d");
        this.shadowContext = this.shadowLayer.getContext("2d");
        this.initPlayGround();
    }

    private initPlayGround() {
        this.canvasElement.setAttribute("width", this.playgroundWidth + 'px');
        this.canvasElement.setAttribute("height", this.playgroundHeight + 'px');
        this.girdLayer.setAttribute("width", this.playgroundWidth + 'px');
        this.girdLayer.setAttribute("height", this.playgroundHeight + 'px');
        this.shadowLayer.setAttribute("width", this.playgroundWidth + 'px');
        this.shadowLayer.setAttribute("height", this.playgroundHeight + 'px');
        let gridWidth: number = getGridWidth(this.playgroundWidth, GridConf.widthGridNum, this.waterTank),
            gridHeight: number = getGridHeight(this.playgroundHeight, GridConf.heightGridNum, this.waterTank);
        currentGridInfo = {
            gridWidth,
            gridHeight,
            waterTank: this.waterTank
        }
        // const self = this;
        this.container.appendChild(this.canvasElement);
        registryDropEvent.bind(this)(this.container);
        this.draw();
    }
    createStructByDrop(structInfo: IStructInitInfo) {
        StructElementMgr.getInstance().createElement(structInfo, this.container, this);
    }
    setPlaygroundSize(playGroundWidth: number, playGroundHeight: number) {
        this.playgroundHeight = playGroundHeight;
        this.playgroundWidth = playGroundWidth;

        this.container.style.width = playGroundWidth + 'px';
        this.container.style.height = playGroundHeight + 'px';
        this.initPlayGround();
    }
    undoShadowStyle() {
        if (currentShowArea.left == 0) {
            return;
        }
        if (!this.shadowContext)
            return;
        try {
            this.shadowContext.clearRect(0, 0, this.playgroundWidth, this.playgroundWidth);
        } catch (ex) {
            console.error(ex)
        }
    }
    getPlayGroundSize() {
        return {
            width: this.playgroundWidth,
            height: this.playgroundHeight
        }
    }
    addShadowStyle(left: number, top: number, width: number, height: number) {
        if (currentShowArea.top != top || currentShowArea.left != left || currentShowArea.width != width || currentShowArea.height != height) {
            this.undoShadowStyle()
        }
        //清空待重回区域
        currentShowArea = {
            top,
            left,
            width,
            height
        }
        if (!this.shadowContext)
            return;
        const leftLocation = getLeft(left, currentGridInfo.gridWidth, currentGridInfo.waterTank) + SplitLineWidth,
            topLocation = getTop(top, currentGridInfo.gridHeight, currentGridInfo.waterTank) + SplitLineWidth,
            areaWith = getWidth(width, currentGridInfo.gridWidth, currentGridInfo.waterTank) - 2,
            areaHeight = getHeight(height, currentGridInfo.gridHeight, currentGridInfo.waterTank) - 2;
        this.shadowContext.fillStyle = ShadowBackgroundColor;
        this.shadowContext.fillRect(leftLocation, topLocation, areaWith, areaHeight);
        this.publishPlayGround();
    }
    private publishPlayGround() {
        this.canvasContext?.clearRect(0, 0, this.playgroundWidth, this.playgroundHeight);
        this.canvasContext?.drawImage(this.shadowLayer, 0, 0, this.playgroundWidth, this.playgroundHeight);
        this.canvasContext?.drawImage(this.girdLayer, 0, 0, this.playgroundWidth, this.playgroundHeight);

    }
    draw(startTop: number = 0, startLeft: number = 0) {
        const gridContext = this.girdLayer.getContext("2d");
        if (!gridContext) {
            return;
        }
        if (this.waterTank == 0) {
            this.drawGrid();
        } else {
            this.drawWaterTankGrid();
        }
        this.publishPlayGround();
    }

    private drawGrid(startTop: number = 0, startLeft: number = 0) {
        const gridContext = this.girdLayer.getContext("2d");
        if (!gridContext) {
            return;
        }
        gridContext.clearRect(0, 0, this.playgroundWidth, this.playgroundHeight);
        const startXLocation = startLeft * currentGridInfo.gridWidth;
        const startYLocation = startTop * currentGridInfo.gridHeight;
        const endXLocation = this.playgroundWidth;
        const endYLocation = this.playgroundHeight;
        for (var i = startXLocation; i <= endXLocation; i += currentGridInfo.gridWidth) {
            gridContext.strokeStyle = this.lineColor;
            gridContext.lineWidth = SplitLineWidth;
            gridContext.beginPath();
            gridContext.moveTo(i, startTop * currentGridInfo.gridHeight);
            gridContext.lineTo(i, this.playgroundHeight);
            gridContext.stroke();
            for (let j = i; j < i + currentGridInfo.gridWidth; j += currentGridInfo.gridWidth / 5) {
                gridContext.strokeStyle = SplitSubLineColor;
                gridContext.lineWidth = SplitLineWidth / 2;
                gridContext.beginPath();
                gridContext.moveTo(j, startTop * currentGridInfo.gridHeight);
                gridContext.lineTo(j, this.playgroundHeight);
                gridContext.stroke();
            }
        }

        // SplitSubLineColor
        for (var i = startYLocation; i <= endYLocation; i += currentGridInfo.gridHeight) {
            gridContext.strokeStyle = this.lineColor;
            gridContext.lineWidth = SplitLineWidth;
            gridContext.beginPath();
            gridContext.moveTo(startLeft * currentGridInfo.gridWidth, i);
            gridContext.lineTo(this.playgroundWidth, i);
            gridContext.stroke();

            for (let j = i; j < i + currentGridInfo.gridHeight; j += currentGridInfo.gridHeight / 5) {
                gridContext.strokeStyle = SplitSubLineColor;
                gridContext.lineWidth = SplitLineWidth / 2;
                gridContext.beginPath();
                gridContext.moveTo(startLeft * currentGridInfo.gridWidth, j);
                gridContext.lineTo(this.playgroundWidth, j);
                gridContext.stroke();
            }
        }
    }
    private drawWaterTankGrid() {
        const gridContext = this.girdLayer.getContext("2d");
        if (!gridContext) {
            return;
        }
        const startXLocation = this.waterTank,
            startYLocation = this.waterTank,
            endXLocation = this.playgroundWidth - this.waterTank - currentGridInfo.gridWidth,
            endYLocation = this.playgroundHeight - this.waterTank - currentGridInfo.gridHeight;
        gridContext.clearRect(0, 0, this.playgroundWidth, this.playgroundHeight);
        for (var i = startXLocation; i <= endXLocation; i += currentGridInfo.gridWidth + this.waterTank) {
            for (let j = startYLocation; j <= endYLocation; j += currentGridInfo.gridHeight + this.waterTank) {
                this.drawTargetWaterTankGrid(gridContext, i, j);
            }

            // gridContext.strokeStyle = SplitLineColor;
            // gridContext.lineWidth = SplitLineWidth;
            // gridContext.strokeRect(i, this.waterTank, currentGridInfo.gridWidth, currentGridInfo.gridHeight);    //红色边框矩形
            // gridContext.strokeStyle = this.lineColor;
            // gridContext.lineWidth = SplitLineWidth;
            // gridContext.beginPath();
            // gridContext.moveTo(i, startTop*currentGridInfo.gridHeight);
            // gridContext.lineTo(i, this.playgroundHeight);
            // gridContext.stroke();
            // for(let j=i;j<i+currentGridInfo.gridWidth;j+=currentGridInfo.gridWidth/5){
            //     gridContext.strokeStyle = SplitSubLineColor;
            //     gridContext.lineWidth = SplitLineWidth/2;
            //     gridContext.beginPath();
            //     gridContext.moveTo(j, startTop*currentGridInfo.gridHeight);
            //     gridContext.lineTo(j, this.playgroundHeight);
            //     gridContext.stroke();
            // }
        }
        // context.strokeRect(100, 100, 60, 60);    //红色边框矩形
    }
    private drawTargetWaterTankGrid(gridContext: CanvasRenderingContext2D, left: number, top: number) {
        gridContext.strokeStyle = SplitLineColor;
        gridContext.lineWidth = SplitLineWidth;

        gridContext.strokeRect(left, top, currentGridInfo.gridWidth, currentGridInfo.gridHeight);
        const spliceWidth = currentGridInfo.gridWidth / 5;
        const spliceHeight = currentGridInfo.gridHeight / 5;
        for (let i = left + spliceWidth; i < left + currentGridInfo.gridWidth; i += spliceWidth) {
            gridContext.strokeStyle = SplitSubLineColor;
            gridContext.lineWidth = SplitLineWidth / 2;
            gridContext.beginPath();
            gridContext.moveTo(i, top);
            gridContext.lineTo(i, top + currentGridInfo.gridHeight);
            gridContext.stroke();
        }
        for (let j = top + spliceHeight; j < top + currentGridInfo.gridHeight; j += spliceHeight) {
            gridContext.strokeStyle = SplitSubLineColor;
            gridContext.lineWidth = SplitLineWidth / 2;
            gridContext.beginPath();
            gridContext.moveTo(left, j);
            gridContext.lineTo(left + currentGridInfo.gridWidth, j);
            gridContext.stroke();
        }

    }


}